<template>
  <section class="card">
    <header class="card-header">
      <div class="title">题目管理</div>
      <div class="ops">
        <el-input v-model="query.keyword" placeholder="按题干搜索" size="small" style="width: 220px"
          @keyup.enter="loadList" />
        <el-select v-model="query.questionType" size="small" placeholder="题型" style="width: 120px">
          <el-option :value="0" label="全部" />
          <el-option :value="1" label="单选" />
          <el-option :value="2" label="多选" />
          <el-option :value="3" label="判断" />
          <el-option :value="4" label="填空" />
        </el-select>
        <el-select v-model="query.difficulty" size="small" placeholder="难度" style="width: 120px">
          <el-option :value="0" label="全部" />
          <el-option :value="1" label="简单" />
          <el-option :value="2" label="一般" />
          <el-option :value="3" label="困难" />
        </el-select>
        <el-button size="small" @click="loadList">查询</el-button>
        <el-button size="small" class="secondary" @click="resetQuery">重置</el-button>
        <el-button size="small" type="primary" @click="openCreate">创建题目</el-button>
      </div>
    </header>
    <div class="card-body">
      <el-table :data="list" border stripe v-loading="loading" style="width: 100%">
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column label="题型" width="100">
          <template #default="{ row }">
            <el-tag :type="typeTagType(row.questionType)">{{ typeText(row.questionType) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="stem" label="题干" min-width="280" />
        <el-table-column label="难度" width="100">
          <template #default="{ row }">
            <el-tag :type="difficultyTagType(row.difficulty)">{{ difficultyText(row.difficulty) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="score" label="分值" width="80" />
        <el-table-column label="选项数" width="90">
          <template #default="{ row }">
            {{ Array.isArray(row.options) ? row.options.length : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="320">
          <template #default="{ row }">
            <el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
            <el-button size="small" type="danger" @click="remove(row)">删除</el-button>
            <el-button size="small" @click="openBind(row)">绑定试卷</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pager">
        <el-pagination background layout="prev, pager, next" :page-size="query.size" :current-page="query.page"
          :total="total" @current-change="handlePage" />
      </div>
    </div>

    <el-dialog :title="dialogTitle" v-model="dialogVisible" width="720px" align-center>
      <el-form :model="form" label-width="100px">
        <el-form-item label="题型">
          <el-select v-model="form.questionType" placeholder="请选择题型" @change="onTypeChange" style="width: 160px">
            <el-option :value="1" label="单选" />
            <el-option :value="2" label="多选" />
            <el-option :value="3" label="判断" />
            <el-option :value="4" label="填空" />
          </el-select>
        </el-form-item>
        <el-form-item label="题干">
          <el-input v-model="form.stem" type="textarea" :rows="3" placeholder="请输入题干" />
        </el-form-item>
        <el-form-item label="解析">
          <el-input v-model="form.analysis" type="textarea" :rows="3" placeholder="题目解析(可选)" />
        </el-form-item>
        <el-form-item label="难度">
          <el-select v-model="form.difficulty" placeholder="选择难度" style="width: 160px">
            <el-option :value="1" label="简单" />
            <el-option :value="2" label="一般" />
            <el-option :value="3" label="困难" />
          </el-select>
        </el-form-item>
        <el-form-item label="分值">
          <el-input-number v-model="form.score" :min="0" :max="1000" />
        </el-form-item>
        <el-form-item label="标签ID">
          <el-input v-model="form.tagIdsText" placeholder="例如: 10,11" />
        </el-form-item>

        <!-- 选项编辑：单选/多选 -->
        <template v-if="form.questionType === 1 || form.questionType === 2">
          <el-divider content-position="left">选项</el-divider>
          <div class="options">
            <div v-for="(opt, idx) in form.options" :key="idx" class="option-row">
              <el-tag type="info" style="width: 42px; text-align: center">{{ opt.optionKey }}</el-tag>
              <el-input v-model="opt.content" placeholder="选项内容" style="flex:1" />
              <div class="correct-flag">
                <span>正确</span>
                <el-switch v-model="opt.isCorrect" :active-value="1" :inactive-value="0"
                  @change="onCorrectChange(idx)" />
              </div>
              <el-button size="small" type="danger" @click="removeOption(idx)">删除</el-button>
            </div>
            <el-button size="small" @click="addOption">添加选项</el-button>
          </div>
        </template>

        <!-- 判断题 -->
        <template v-else-if="form.questionType === 3">
          <el-divider content-position="left">判断题答案</el-divider>
          <el-radio-group v-model="form.boolCorrect">
            <el-radio :label="true">正确</el-radio>
            <el-radio :label="false">错误</el-radio>
          </el-radio-group>
        </template>

        <!-- 填空题 -->
        <template v-else-if="form.questionType === 4">
          <el-divider content-position="left">填空答案</el-divider>
          <div class="options">
            <div v-for="(blank, idx) in form.blanks" :key="idx" class="option-row">
              <el-tag type="info" style="width: 72px; text-align: center">空{{ idx + 1 }}</el-tag>
              <el-input v-model="form.blanks[idx]" placeholder="正确答案" style="flex:1" />
              <el-button size="small" type="danger" @click="removeBlank(idx)">删除</el-button>
            </div>
            <el-button size="small" @click="addBlank">添加空</el-button>
          </div>
        </template>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submit">保存</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 绑定试卷弹窗 -->
    <el-dialog title="绑定试卷" v-model="bindDialogVisible" width="520px" align-center>
      <div class="bind-form">
        <div class="row">
          <span class="label">选择试卷</span>
          <div class="inline">
            <el-input v-model="bindQuery.keyword" placeholder="按名称搜索" size="small" style="width: 220px"
              @keyup.enter="loadBindPapers" />
            <el-button size="small" @click="loadBindPapers">查询</el-button>
          </div>
        </div>
        <el-select v-model="bindForm.paperId" filterable placeholder="请选择试卷" style="width: 100%">
          <el-option v-for="p in bindPapers" :key="p.id" :label="p.name" :value="p.id" />
        </el-select>
        <div class="row mt">
          <span class="label">排序</span>
          <el-input-number v-model="bindForm.sortOrder" :min="1" :max="9999" />
        </div>
        <div class="row">
          <span class="label">分值</span>
          <el-input-number v-model="bindForm.score" :min="0" :max="1000" />
        </div>
        <div class="row">
          <span class="label">是否必答</span>
          <el-switch v-model="bindForm.required" :active-value="1" :inactive-value="0" />
        </div>
        <div class="row">
          <span class="label">评分配置 JSON</span>
          <el-input v-model="bindForm.scoringConfigJson" type="textarea" :rows="3"
            placeholder="可选，如 {\'blankEach\':1}" />
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="bindDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitBind">绑定</el-button>
        </div>
      </template>
    </el-dialog>
  </section>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { pageQuestions, createQuestion, updateQuestion, deleteQuestion, getQuestionDetail, pagePapers, createPaperQuestion } from '@/api/exam/exam'

interface QuestionOption { optionKey: string; content: string; isCorrect?: number }

const list = ref<any[]>([])
const loading = ref(false)
const total = ref(0)
const query = reactive({ keyword: '', questionType: 0 as number, difficulty: 0 as number, page: 1, size: 10 })

function typeText(t?: number) {
  return t === 1 ? '单选' : t === 2 ? '多选' : t === 3 ? '判断' : t === 4 ? '填空' : '-'
}
function typeTagType(t?: number) {
  return t === 1 ? 'success' : t === 2 ? 'warning' : t === 3 ? 'info' : t === 4 ? 'primary' : 'default'
}
function difficultyText(d?: number) {
  return d === 1 ? '简单' : d === 2 ? '一般' : d === 3 ? '困难' : '-'
}
function difficultyTagType(d?: number) {
  return d === 1 ? 'success' : d === 2 ? 'warning' : d === 3 ? 'danger' : 'default'
}

async function loadList() {
  loading.value = true
  try {
    const params: Record<string, any> = {
      page: query.page,
      size: query.size,
    }
    if (query.keyword) params.keyword = query.keyword
    if (query.questionType) params.questionType = query.questionType
    if (query.difficulty) params.difficulty = query.difficulty
    const res = await pageQuestions(params)
    const raw = res?.data?.data ?? res?.data
    if (Array.isArray(raw)) {
      list.value = raw
      total.value = raw.length
    } else {
      list.value = raw?.list ?? []
      total.value = raw?.total ?? 0
      if (raw?.page != null) query.page = raw.page
      if (raw?.size != null) query.size = raw.size
    }
  } catch (e) {
    ElMessage.error('加载题目失败')
  } finally {
    loading.value = false
  }
}

function resetQuery() {
  query.keyword = ''
  query.questionType = 0
  query.difficulty = 0
  query.page = 1
  loadList()
}

function handlePage(p: number) {
  query.page = p
  loadList()
}

// 创建/编辑
const dialogVisible = ref(false)
const dialogTitle = ref('创建题目')
const form = reactive({
  id: undefined as number | undefined,
  questionType: 1 as 1 | 2 | 3 | 4,
  stem: '',
  analysis: '',
  difficulty: 1 as 1 | 2 | 3,
  score: 2,
  options: [] as QuestionOption[],
  // 判断题
  boolCorrect: true as boolean,
  // 填空题
  blanks: [] as string[],
  // 标签
  tagIdsText: '' as string,
})

function initOptionsForSingle() {
  form.options = [
    { optionKey: 'A', content: '', isCorrect: 1 },
    { optionKey: 'B', content: '', isCorrect: 0 },
  ]
}
function initOptionsForMultiple() {
  form.options = [
    { optionKey: 'A', content: '', isCorrect: 0 },
    { optionKey: 'B', content: '', isCorrect: 0 },
  ]
}
function onTypeChange() {
  if (form.questionType === 1) initOptionsForSingle()
  else if (form.questionType === 2) initOptionsForMultiple()
  else if (form.questionType === 3) {
    form.boolCorrect = true
    form.options = []
    form.blanks = []
  } else if (form.questionType === 4) {
    form.blanks = ['']
    form.options = []
  }
}

function addOption() {
  const nextKeyCode = 65 + form.options.length // 65:'A'
  const key = String.fromCharCode(nextKeyCode)
  form.options.push({ optionKey: key, content: '', isCorrect: 0 })
}
function removeOption(idx: number) {
  if (form.options.length <= 2) {
    ElMessage.warning('至少保留两个选项')
    return
  }
  form.options.splice(idx, 1)
}
function onCorrectChange(idx: number) {
  if (form.questionType === 1) {
    // 单选：确保只有一个正确
    form.options.forEach((o, i) => {
      o.isCorrect = i === idx ? 1 : 0
    })
  }
}

function addBlank() {
  form.blanks.push('')
}
function removeBlank(idx: number) {
  if (form.blanks.length <= 1) {
    ElMessage.warning('至少保留一个空')
    return
  }
  form.blanks.splice(idx, 1)
}

function openCreate() {
  dialogTitle.value = '创建题目'
  form.id = undefined
  form.questionType = 1
  form.stem = ''
  form.analysis = ''
  form.difficulty = 1
  form.score = 2
  form.tagIdsText = ''
  form.boolCorrect = true
  form.blanks = []
  initOptionsForSingle()
  dialogVisible.value = true
}

async function openEdit(row: any) {
  dialogTitle.value = '编辑题目'
  try {
    const res = await getQuestionDetail(row.id)
    const q = res?.data?.data ?? res?.data
    form.id = q.id
    form.questionType = q.questionType
    form.stem = q.stem
    form.analysis = q.analysis ?? ''
    form.difficulty = q.difficulty ?? 1
    form.score = q.score ?? 2
    form.tagIdsText = Array.isArray(q.tagIds) ? q.tagIds.join(',') : ''
    if (q.questionType === 3) {
      // 判断题：根据正确项恢复布尔
      const correctOpt = Array.isArray(q.options) ? q.options.find((o: any) => o.isCorrect === 1) : undefined
      form.boolCorrect = correctOpt ? (correctOpt.optionKey === 'A' || correctOpt.content === '是') : true
      form.options = []
      form.blanks = []
    } else if (q.questionType === 4) {
      // 填空题：从 options 转 blanks
      const blanks = Array.isArray(q.options) ? q.options.filter((o: any) => String(o.optionKey).startsWith('blank_')) : []
      blanks.sort((a: any, b: any) => Number(String(a.optionKey).split('_')[1] ?? 0) - Number(String(b.optionKey).split('_')[1] ?? 0))
      form.blanks = blanks.map((o: any) => o.content || '')
      if (form.blanks.length === 0) form.blanks = ['']
      form.options = []
    } else {
      // 单选/多选：直接填充选项
      form.options = Array.isArray(q.options) ? q.options.map((o: any) => ({ optionKey: o.optionKey, content: o.content, isCorrect: o.isCorrect ? 1 : 0 })) : []
      if (form.options.length < 2) {
        // 兜底确保至少两个选项
        initOptionsForSingle()
      }
    }
    dialogVisible.value = true
  } catch (e) {
    ElMessage.error('加载题目详情失败')
  }
}

function parseTagIds(text: string): number[] | undefined {
  if (!text) return undefined
  const arr = text
    .split(/[,，\s]+/)
    .map((s) => Number(s))
    .filter((n) => !Number.isNaN(n) && n > 0)
  return arr.length ? arr : undefined
}

async function submit() {
  // 基本校验
  if (!form.stem || !String(form.stem).trim()) {
    ElMessage.warning('请填写题干')
    return
  }
  if (!form.score || form.score < 0) {
    ElMessage.warning('请填写有效分值')
    return
  }

  // 构建 payload.options
  let options: QuestionOption[] | undefined
  if (form.questionType === 1 || form.questionType === 2) {
    if (form.options.length < 2) {
      ElMessage.warning('至少设置两个选项')
      return
    }
    if (form.questionType === 1) {
      const correctCount = form.options.filter((o) => o.isCorrect === 1).length
      if (correctCount !== 1) {
        ElMessage.warning('单选题必须且只能设置一个正确选项')
        return
      }
    }
    options = form.options.map((o) => ({ optionKey: o.optionKey, content: o.content, isCorrect: o.isCorrect ? 1 : 0 }))
  } else if (form.questionType === 3) {
    options = [
      { optionKey: 'A', content: '是', isCorrect: form.boolCorrect ? 1 : 0 },
      { optionKey: 'B', content: '否', isCorrect: form.boolCorrect ? 0 : 1 },
    ]
  } else if (form.questionType === 4) {
    if (!form.blanks.length || form.blanks.some((b) => !b || !String(b).trim())) {
      ElMessage.warning('请填写至少一个有效的填空答案')
      return
    }
    options = form.blanks.map((b, i) => ({ optionKey: `blank_${i + 1}`, content: b, isCorrect: 1 }))
  }

  const payload: any = {
    questionType: form.questionType,
    stem: form.stem,
    analysis: form.analysis || undefined,
    difficulty: form.difficulty,
    score: form.score,
    options,
  }
  const tags = parseTagIds(form.tagIdsText)
  if (tags) payload.tagIds = tags

  try {
    if (form.id) {
      await updateQuestion(form.id, payload)
      ElMessage.success('题目更新成功')
    } else {
      await createQuestion(payload)
      ElMessage.success('题目创建成功')
    }
    dialogVisible.value = false
    loadList()
  } catch (e) {
    ElMessage.error('保存失败')
  }
}

function remove(row: any) {
  ElMessageBox.confirm(`确认删除题目【${typeText(row.questionType)}-${row.id}】吗？该操作不可恢复。`, '提示', { type: 'warning' })
    .then(async () => {
      try {
        await deleteQuestion(row.id)
        ElMessage.success('删除成功')
        loadList()
      } catch (e) {
        ElMessage.error('删除失败')
      }
    })
    .catch(() => { })
}

onMounted(loadList)

// 绑定试卷相关
const bindDialogVisible = ref(false)
const currentQuestion = ref<any | null>(null)
const bindQuery = reactive({ keyword: '' })
const bindPapers = ref<any[]>([])
const bindForm = reactive({ paperId: undefined as number | undefined, sortOrder: 1, score: 2, required: 1 as 0 | 1, scoringConfigJson: '' })

async function loadBindPapers() {
  try {
    const res = await pagePapers({ keyword: bindQuery.keyword, page: 1, size: 50 })
    const raw = res?.data?.data ?? res?.data
    bindPapers.value = Array.isArray(raw) ? raw : (raw?.list ?? [])
  } catch (e) {
    bindPapers.value = []
  }
}

function openBind(row: any) {
  currentQuestion.value = row
  bindForm.paperId = undefined
  bindForm.sortOrder = 1
  bindForm.score = row.score ?? 2
  bindForm.required = 1
  bindForm.scoringConfigJson = ''
  bindDialogVisible.value = true
  loadBindPapers()
}

async function submitBind() {
  if (!currentQuestion.value?.id) { ElMessage.warning('题目不存在'); return }
  if (!bindForm.paperId) { ElMessage.warning('请选择试卷'); return }
  try {
    const payload = {
      paperId: bindForm.paperId,
      questionId: currentQuestion.value.id,
      sortOrder: bindForm.sortOrder,
      score: bindForm.score,
      required: bindForm.required,
      scoringConfigJson: bindForm.scoringConfigJson || undefined,
    }
    const res = await createPaperQuestion(payload as any)
    const ok = (res?.data?.code ?? res?.data?.status ?? 0) === 0
    if (ok) {
      ElMessage.success('绑定成功')
      bindDialogVisible.value = false
    } else {
      ElMessage.error('绑定失败')
    }
  } catch (e) {
    ElMessage.error('绑定失败')
  }
}
</script>

<style scoped>
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 6px 12px 6px;
  border-bottom: 1px solid #f0f0f0;
}

.card-header .title {
  font-weight: 600;
}

.card-header .ops {
  display: flex;
  gap: 8px;
  align-items: center;
}

.card-body {
  padding-top: 12px;
}

.pager {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.dialog-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.options {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.option-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.correct-flag {
  display: flex;
  align-items: center;
  gap: 6px;
}

.bind-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bind-form .row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.bind-form .row .label {
  width: 90px;
  color: #666;
}

.bind-form .row.mt {
  margin-top: 8px;
}
</style>
